using System;
using System.Diagnostics;
using System.Globalization;

namespace Atomic.Libraries.Physics.Units
{
	[Serializable]
	[DebuggerDisplay("{DebuggerDisplay}")]
	public class Mass : IQuantity
	{
		private double value;
		//private IUnitSystem system;

		private Mass(double value)
		{
			this.value = value;
		}

		public static Mass FromUnit(IUnitSystem system, double value)
		{
			// http://en.wikipedia.org/w/index.php?title=International_System_of_Units&oldid=596637756#Derived_units
			return new Mass(value / (system.EnergyScaling * system.TimeScaling * system.TimeScaling / (system.LengthScaling * system.LengthScaling)));
		}

		public static Mass FromElectronVoltSquareMeterPerSquareSecond(double value)
		{
			// The "natural" unit.
			return FromUnit(UnitSystem.AtomicSystem, value);
		}

		/// <summary>
		/// The atomic mass unit (u or Da). One unified atomic mass unit is approximately the mass of a nucleon and is equivalent to 1 g/mol.
		/// </summary>
		public static Mass FromDalton(double value)
		{
			// http://en.wikipedia.org/w/index.php?title=Atomic_mass_unit&oldid=597999802
			return FromKiloGram(value * 1.66053892173e-27);
		}

		public static Mass FromKiloGram(double value)
		{
			return FromUnit(UnitSystem.InternationalSystem, value);
		}

		public double ToUnit(IUnitSystem system)
		{
			return value * system.EnergyScaling * system.TimeScaling * system.TimeScaling / (system.LengthScaling * system.LengthScaling);
		}

		public double ToElectronVoltSquareMeterPerSquareSecond()
		{
			return ToUnit(UnitSystem.AtomicSystem);
		}

		/// <summary>
		/// The atomic mass unit (u or Da). One unified atomic mass unit is approximately the mass of a nucleon and is equivalent to 1 g/mol.
		/// </summary>
		public double ToDalton()
		{
			return ToKiloGram() / 1.66053892173e-27;
		}

		public double ToKiloGram()
		{
			return ToUnit(UnitSystem.InternationalSystem);
		}

		public static implicit operator double(Mass value)
		{
			return value.ToElectronVoltSquareMeterPerSquareSecond();
		}

		public static implicit operator Mass(double value)
		{
			return FromElectronVoltSquareMeterPerSquareSecond(value);
		}

		private string DebuggerDisplay
		{
			get
			{
				return string.Format(CultureInfo.InvariantCulture, "{0} eV*m^2/s^2 = {1} u = {2} kg", ToElectronVoltSquareMeterPerSquareSecond(), ToDalton(), ToKiloGram());
			}
		}
	}
}
